<?php

namespace Kunfeng\Dify\Exception;

/**
 * 网络异常类
 */
class NetworkException extends DifyApiException
{
    private $retryable;

    public function __construct(
        string $message,
        int $statusCode = 0,
        array $responseData = [],
        bool $retryable = false,
        \Throwable $previous = null
    ) {
        parent::__construct($message, $statusCode, $responseData, $previous);
        $this->retryable = $retryable;
    }

    /**
     * 判断是否可重试
     */
    public function isRetryable(): bool
    {
        return $this->retryable;
    }

    /**
     * 从 Guzzle 异常创建网络异常
     */
    public static function fromGuzzleException(\GuzzleHttp\Exception\GuzzleException $e): self
    {
        $retryable = false;
        $statusCode = 0;
        $responseData = [];

        if ($e instanceof \GuzzleHttp\Exception\ConnectException) {
            $message = 'Network connection failed: ' . $e->getMessage();
            $retryable = true;
        } elseif ($e instanceof \GuzzleHttp\Exception\RequestException) {
            $response = $e->getResponse();
            if ($response) {
                $statusCode = $response->getStatusCode();
                $body = $response->getBody()->getContents();
                $responseData = json_decode($body, true) ?: [];
                
                // 5xx 错误通常可以重试
                if ($statusCode >= 500) {
                    $retryable = true;
                    $message = 'Server error: ' . $e->getMessage();
                } else {
                    $message = 'Request failed: ' . $e->getMessage();
                }
            } else {
                $message = 'Request failed: ' . $e->getMessage();
                $retryable = true;
            }
        } else {
            $message = 'Network error: ' . $e->getMessage();
            $retryable = true;
        }

        return new self($message, $statusCode, $responseData, $retryable, $e);
    }
}
